package org.fujay.langchain4jserver.domain.application.entity;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.fujay.langchain4jserver.domain.application.vo.AppConfigSnapshot;
import org.fujay.langchain4jserver.domain.application.vo.AppId;
import org.fujay.langchain4jserver.domain.application.vo.Version;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 应用配置历史记录实体
 */
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE) // Private constructor for factory methods
public class AppConfigHistory {

    /**
     * 历史记录ID (主键)
     */
    private Long id;

    /**
     * 关联的应用ID
     */
    private AppId appId;

    /**
     * 版本
     */
    private Version version;

    /**
     * 配置快照
     */
    private AppConfigSnapshot configSnapshot;

    /**
     * 变更描述
     */
    private String changeDescription;

    /**
     * 变更人
     */
    private String changedBy;

    /**
     * 变更时间
     */
    private LocalDateTime changeTime;

    /**
     * 工厂方法：创建一个新的配置历史记录 (ID 为 null)
     *
     * @param appId             关联的应用ID
     * @param version           版本
     * @param configSnapshot    配置快照
     * @param changeDescription 变更描述
     * @param changedBy         变更人
     * @return 新的 AppConfigHistory 实例
     */
    public static AppConfigHistory create(
            AppId appId,
            Version version,
            AppConfigSnapshot configSnapshot,
            String changeDescription,
            String changedBy) {
        Assert.notNull(appId, "AppId cannot be null");
        Assert.notNull(version, "Version cannot be null");
        Assert.notNull(configSnapshot, "Config snapshot cannot be null");
        // changedBy can be null or empty depending on context (e.g., system change)
        // changeDescription can be null or empty
        return new AppConfigHistory(
                null, appId, version, configSnapshot, changeDescription, changedBy, LocalDateTime.now());
    }

    /**
     * 工厂方法：加载一个已存在的配置历史记录
     *
     * @param id                历史记录ID
     * @param appId             关联的应用ID
     * @param version           版本
     * @param configSnapshot    配置快照
     * @param changeDescription 变更描述
     * @param changedBy         变更人
     * @param changeTime        变更时间
     * @return AppConfigHistory 实例
     */
    public static AppConfigHistory load(
            Long id,
            AppId appId,
            Version version,
            AppConfigSnapshot configSnapshot,
            String changeDescription,
            String changedBy,
            LocalDateTime changeTime) {
        Assert.notNull(id, "ID cannot be null for loading");
        Assert.notNull(appId, "AppId cannot be null");
        Assert.notNull(version, "Version cannot be null");
        Assert.notNull(configSnapshot, "Config snapshot cannot be null");
        Assert.notNull(changeTime, "ChangeTime cannot be null");
        // Allow null/empty for changeDescription and changedBy when loading
        return new AppConfigHistory(
                id, appId, version, configSnapshot, changeDescription, changedBy, changeTime);
    }

    /**
     * 判断是否是新创建的实体 (ID 为 null)
     *
     * @return 如果是新实体，返回 true，否则返回 false
     */
    public boolean isNew() {
        return this.id == null;
    }

    // equals and hashCode based on ID
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AppConfigHistory that = (AppConfigHistory) o;

        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;
    }
}
